#define _CRT_SECURE_NO_WARNINGS 1 

#include"class.h"

void Date::Print()const
{
	cout << _year << '-' << _month << '-' << _day << endl;
}

bool Date::CheckDate()const
{
	if (_year<0
		||_month>12
		||_month<1
		|| _day < 1 
		|| _day > GetMonthDay(_year, _month))
	{
		return false;
	}
	else
			return true;

}

int Date::GetMonthDay(int year, int month)const
{
	assert(month > 0 && 13 > month);
	static int Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if ((month == 2) && ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
		Month[2] = 29;
	else
		Month[2] = 28;
	return Month[month];
}

Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
	if (!CheckDate())
		cout << "Date False!" << endl;
}

Date::Date(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

Date::~Date()
{
	this->_year = 0;
	this->_month = 0;
	this->_day = 0;
}

Date* Date::operator&()
{
	return this;
}

const Date* Date:: operator&()const
{
	return this;
}

Date& Date::operator=(const Date& d)
{
	if (this != &d)
	{
		this->_year = d._year;
		this->_month = d._month;
		this->_day = d._day;
	}
	return *this;
}

Date Date::operator+(int day)const
{
	Date temp = *this;
	int Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (((temp._year % 4 == 0) && (temp._year % 100 != 0)) || (temp._year % 400 == 0))
		Month[2] = 29;
	else
		Month[2] = 28;
	int year = temp._year;
	int month = temp._month;
	int Day = temp._day;
	Day += day;
	while (Day > Month[month])
	{
		Day -= Month[month];
		month++;
		if (month > 12)
		{
			month = 1;
			year++;

			if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
				Month[2] = 29;
			else
				Month[2] = 28;
		}
	}
	temp._year = year;
	temp._month = month;
	temp._day = Day;
	return temp;
}


Date& Date::operator+=(int day)
{
	int Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (((this->_year % 4 == 0) && (this->_year % 100 != 0)) || (this->_year % 400 == 0))
		Month[2] = 29;
	else
		Month[2] = 28;
	int year = this->_year;
	int month = this->_month;
	int Day = this->_day;
	Day += day;
	while (Day > Month[month])
	{
		Day -= Month[month];
		month++;
		if (month > 12)
		{
			month = 1;
			year++;

			if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
				Month[2] = 29;
			else
				Month[2] = 28;
		}
	}
	this->_year = year;
	this->_month = month;
	this->_day = Day;
	return *this;
}

Date Date::operator-(int day)const
{
	Date temp = (*this);
	int Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (((temp._year % 4 == 0) && (temp._year % 100 != 0)) || (temp._year % 400 == 0))
		Month[2] = 29;
	else
		Month[2] = 28;
	int year = temp._year;
	int month = temp._month;
	int Day = temp._day;
	Day -= day;
	while (Day <= 0) {
		month--;
		if (month < 1) {
			month = 12;
			year--;
			if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
				Month[2] = 29;
			else
				Month[2] = 28;
		}
		Day += Month[month];
	}
	temp._year = year;
	temp._month = month;
	temp._day = Day;
	return temp;
}

Date& Date::operator-=(int day)
{
	int Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (((this->_year % 4 == 0) && (this->_year % 100 != 0)) || (this->_year % 400 == 0))
		Month[2] = 29;
	else
		Month[2] = 28;
	int year = this->_year;
	int month = this->_month;
	int Day = this->_day;
	Day -= day;
	while (Day <= 0) {
		month--;
		if (month < 1) {
			month = 12;
			year--;
			if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
				Month[2] = 29;
			else
				Month[2] = 28;
		}
		Day += Month[month];
	}
	this->_year = year;
	this->_month = month;
	this->_day = Day;
	return *this;
}

Date& Date::operator++()
{
	int Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (((this->_year % 4 == 0) && (this->_year % 100 != 0)) || (this->_year % 400 == 0))
		Month[2] = 29;
	else
		Month[2] = 28;
	int year = this->_year;
	int month = this->_month;
	int day = this->_day;
	if (day < Month[month])
		this->_day++;
	else if ((day == Month[month]) && (month < 12))
	{
		this->_month++;
		this->_day = 1;
	}
	else
	{
		this->_year++;
		this->_month = 1;
		this->_day = 1;
	}

	return *this;
}

Date Date::operator++(int)
{
	Date temp = (*this);
	int Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (((this->_year % 4 == 0) && (this->_year % 100 != 0)) || (this->_year % 400 == 0))
		Month[2] = 29;
	else
		Month[2] = 28;
	int year = this->_year;
	int month = this->_month;
	int day = this->_day;
	if (day < Month[month])
		this->_day++;
	else if ((day == Month[month]) && (month < 12))
	{
		this->_month++;
		this->_day = 1;
	}
	else
	{
		this->_year++;
		this->_month = 1;
		this->_day = 1;
	}

	return temp;
}

Date Date::operator--(int)
{
	Date temp = (*this);
	int Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (((temp._year % 4 == 0) && (temp._year % 100 != 0)) || (temp._year % 400 == 0))
		Month[2] = 29;
	else
		Month[2] = 28;
	int year = temp._year;
	int month = temp._month;
	int Day = temp._day;
	Day--;
	while (Day <= 0) {
		month--;
		if (month < 1) {
			month = 12;
			year--;
			if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
				Month[2] = 29;
			else
				Month[2] = 28;
		}
		Day += Month[month];
	}
	temp._year = year;
	temp._month = month;
	temp._day = Day;

	return temp;
}

Date& Date::operator--()
{
	int Month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (((this->_year % 4 == 0) && (this->_year % 100 != 0)) || (this->_year % 400 == 0))
		Month[2] = 29;
	else
		Month[2] = 28;
	int year = this->_year;
	int month = this->_month;
	int Day = this->_day;
	Day--;
	while (Day <= 0) {
		month--;
		if (month < 1) {
			month = 12;
			year--;
			if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
				Month[2] = 29;
			else
				Month[2] = 28;
		}
		Day += Month[month];
	}
	this->_year = year;
	this->_month = month;
	this->_day = Day;
	return *this;
}

bool Date::operator>(const Date& d)const
{
	if (_year > d._year)
		return true;
	else if (_year == d._year)
	{
		if (_month > d._month)
			return true;
		else if (_month == d._month)
			return _day > d._day;
	}

	return false;
}

bool Date::operator==(const Date& d)const
{
	return _year == d._year
		&& _month == d._month
		&& _day == d._day;
}

bool Date::operator >= (const Date& d)const
{
	return ((*this > d) || (*this == d));
}

bool Date::operator < (const Date& d)const
{
	return !(*this >= d);
}

bool Date::operator <= (const Date& d)const
{
	return ((*this < d) || (*this == d));
}

bool Date::operator != (const Date& d)const
{
	return !(*this == d);
}

int Date::operator-(const Date& d)
{
	Date max = (*this);
	Date min = d;
	int flag = 1;
	if (max < min)
	{
		flag = -1;
		Date temp = max;
		max = min;
		min = temp;
	}
	int count = 0;
	while (max != min)
	{
		min++;
		count++;
	}
	return -flag * count;
}

ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "-" << d._month << "-" << d._day << endl;
	return out;
}

istream& operator>>(istream& in, Date& d)
{
	while (1)
	{
		in >> d._year >> d._month >> d._day;
		if (d.CheckDate())
		{
			break;
		}
		cout << "Enter Date False! Please Try Again!" << endl;
	}
	return in;
}